package org.springmvc.service;

import java.util.HashSet;
import java.util.List;

import org.springmvc.dao.AbstractBaseDao;
import org.springmvc.model.BaseEntity;
import org.springmvc.util.BeanUtils;

/**
 * 抽象基础服务
 * @author 唐家林
 * @time 2014年9月5日
 * @param <E>
 */
public abstract class AbstractBaseService<E extends BaseEntity> {
	/**
	 * Bean拷贝时过滤的属性
	 */
//	private final static String[] $ignoreProperties = { "id", "version" , "isDeleted", "createTime", "createBy", "updateTime", "updateBy" };
//	/**
//	 * 获取Bean拷贝时过滤的属性
//	 * @param ignoreProperties 添加新的需要过滤的属性
//	 * @return 返回默认的拷贝过滤的属性和新添加的属性
//	 */
//	protected String[] getIgnoreProperties (String... ignoreProperties) {
//		if (null != ignoreProperties && ignoreProperties.length > 0) {
//			int size = $ignoreProperties.length + ignoreProperties.length;
//			String[] $ignore = new String[size];
//			int index = 0;
//			for (; index < $ignoreProperties.length; index++) {
//				$ignore[index] = $ignoreProperties[index];
//			}
//			for (; index < size; index++) {
//				$ignore[index] = ignoreProperties[index];
//			}
//			return $ignore;
//		} else {
//			return $ignoreProperties;
//		}
//	}
	private final static HashSet<String> $ignoreProperties = new HashSet<String>();
	static {
		$ignoreProperties.add("id");
		$ignoreProperties.add("version");
		$ignoreProperties.add("isDeleted");
		$ignoreProperties.add("createTime");
		$ignoreProperties.add("createBy");
		$ignoreProperties.add("updateTime");
		$ignoreProperties.add("updateBy");
		$ignoreProperties.add("deleteTime");
		$ignoreProperties.add("deleteBy");
	}
	/**
	 * 获取Bean拷贝时过滤的属性
	 * 
	 * <pre>
	 * id
	 * version
	 * isDeleted
	 * createTime
	 * createBy
	 * updateTime
	 * updateBy
	 * deleteTime
	 * deleteBy
	 * </pre>
	 * 
	 * @param ignoreProperties 添加新的需要过滤的属性
	 * @return 返回需要过滤的默认的属性(注释头部包含的属性)和新添加的属性
	 */
	protected HashSet<String> addIgnoreProperties (String... ignoreProperties) {
		HashSet<String> $ignore = null;
		if (null != ignoreProperties && ignoreProperties.length > 0) {
			$ignore = new HashSet<String>($ignoreProperties.size() + ignoreProperties.length);
			$ignore.addAll($ignoreProperties);
			for (int index = 0; index < ignoreProperties.length; index++) {
				$ignore.add(ignoreProperties[index]);
			}
			return $ignore;
		} else {
			$ignore = new HashSet<String>($ignoreProperties.size());
			$ignore.addAll($ignoreProperties);
		}
		return $ignore;
	}

	private AbstractBaseDao<E> baseDao;
	
	public void setBaseDao(AbstractBaseDao<E> baseDao) {
		this.baseDao = baseDao;
	}

	/**
	 * 获取实体对象实例
	 * 
	 * @param id
	 *            实体主键
	 * @return 返回获取的实体对象实例
	 */
	public E get(Integer id) {
		return baseDao.get(id);
	};

	/**
	 * 保存(新增或修改)实体
	 * 
	 * @param e
	 *            期望保存的实体对象实例
	 * @return 返回保存的实体对象实例
	 */
	public E createOrUpdate(E e) {
		if (e.getId() == null) {
			e = baseDao.save(e);
		} else {
			E oldE = baseDao.get(e.getId());
			BeanUtils.copyProperties(e, oldE, $ignoreProperties);
			e = baseDao.update(oldE);
		}
		return e;
	};

	/**
	 * 保存(新增或修改)实体
	 * @param e 期望保存的实体对象实例
	 * @param ignoreProperties 需要忽略的字段
	 * @return 返回保存的实体对象实例
	 */
	public E createOrUpdate(E e, HashSet<String> ignoreProperties) {
		if (e.getId() == null) {
			e = baseDao.save(e);
		} else {
			E oldE = baseDao.get(e.getId());
			BeanUtils.copyProperties(e, oldE, ignoreProperties);
			e = baseDao.update(oldE);
		}
		return e;
	};

	/**
	 * 物理删除单实体
	 * 
	 * @param e
	 *            期望删除的实体对象实例
	 */
	public void delete(E e) {
		baseDao.delete(e);
	}

	/**
	 * 物理删除单实体
	 * 
	 * @param id
	 *            期望删除的实体主键
	 */
	public void delete(Integer id) {
		baseDao.delete(id);
	}

	/**
	 * 物理删除多实体
	 * 
	 * @param es
	 *            期望删除的多个实体对象实例
	 */
	public void delete(List<E> es) {
		baseDao.delete(es);
	}

	/**
	 * 物理删除多实体
	 * 
	 * @param ids
	 *            期望删除的多个实体主键
	 */
	public void delete(Integer[] ids) {
		baseDao.delete(ids);
	}

	/**
	 * 物理删除所有实体
	 * 
	 * @return 返回删除的行数
	 */
	public int deleteAll() {
		return baseDao.deleteAll();
	}

	/**
	 * 逻辑删除单实体
	 * 
	 * @param e
	 *            期望删除的实体对象实例
	 */
	public void logicDelete(E e) {
		baseDao.logicDelete(e);
	}

	/**
	 * 逻辑删除单实体
	 * 
	 * @param id
	 *            期望删除的实体主键
	 */
	public void logicDelete(Integer id) {
		baseDao.logicDelete(id);
	}

	/**
	 * 逻辑删除多实体
	 * 
	 * @param es
	 *            希望删除的多个实体对象实例
	 */
	public void logicDeleteList(List<E> es) {
		baseDao.logicDelete(es);
	}

	/**
	 * 逻辑删除多实体
	 * 
	 * @param ids
	 *            期望删除的多个实体主键
	 */
	public void logicDelete(Integer[] ids) {
		baseDao.logicDelete(ids);
	}
	
	/**
	 * 恢复逻辑删除的单实体
	 * 
	 * @param e
	 *            期望删除的实体对象实例
	 */
	public void disLogicDelete(E e) {
		baseDao.disLogicDelete(e);
	}
	
	/**
	 * 恢复逻辑删除的单实体
	 * 
	 * @param id
	 *            期望删除的实体主键
	 */
	public void disLogicDelete(Integer id) {
		baseDao.disLogicDelete(id);
	}
	
	/**
	 * 恢复逻辑删除的多实体
	 * 
	 * @param es
	 *            希望删除的多个实体对象实例
	 */
	public void disLogicDelete(List<E> es) {
		baseDao.disLogicDelete(es);
	}
	
	/**
	 * 恢复逻辑删除的多实体
	 * 
	 * @param ids
	 *            期望删除的多个实体主键
	 */
	public void disLogicDelete(Integer[] ids) {
		baseDao.disLogicDelete(ids);
	}

}
